package com.custom.action.dbaction;

import com.custom.comm.utils.AssertUtil;
import com.custom.comm.utils.ReflectUtil;
import com.custom.jdbc.executor.convert.AbstractRsHandler;
import com.custom.jdbc.handler.TypeHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * 顶级表解析模板对象
 * @author   Xiao-Bai
 * @since  2021/12/1 23:44
 */
public abstract class AbstractTableModel<T> {

    private static final Logger logger = LoggerFactory.getLogger(AbstractTableModel.class);

    /**
     * 表名
     */
    private String table;

    /**
     * 表的别名
     */
    private String alias;

    public String getTable() {
        return table;
    }

    public void setTable(String table) {
        this.table = table;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    /**
     * 获取实体中指定字段的值
     * x: 实例对象
     * fieldName: 字段名称
     */
    protected Object getFieldValue(T x, String fieldName)
            throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, NoSuchFieldException {
        return ReflectUtil.readFieldValue(x, fieldName);
    }

    /**
     * 将值设置进实体的指定属性中
     */
    protected void setFieldValue(T entity, Field field, Object value) {
        AssertUtil.npe(entity);
        try {
            ReflectUtil.writeFieldValue(value, entity, field.getName(), field.getType());
        }catch (NoSuchFieldException e) {
            logger.error(e.toString(), e);
        }
    }

    /**
     * 获取类型映射处理对象
     */
    public TypeHandler<?> getTypeHandler() {
        try {
            return ReflectUtil.getInstance(getTypeHandlerClass());
        }catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return AbstractRsHandler.getTargetTypeHandler(Object.class);
    }


    public abstract String createTableSql();
    protected abstract Object getValue(T x);
    protected abstract void setValue(T obj, Object value);
    public abstract String getFieldSql();
    protected abstract String getSelectFieldSql();
    public abstract String getSelectFieldSql(String alias);

    public abstract Class<? extends TypeHandler<?>> getTypeHandlerClass();

}
